﻿using System;
using MathNet.Numerics.LinearAlgebra;
using MentalAlchemy.Atomics;

namespace MentalAlchemy.Molecules.MachineLearning
{
	/// <summary>
	/// [molecule]
	/// 
	/// Class to find linear regression coefficients.
	/// </summary>
	[Serializable]
	public class LinearRegression
	{
		/// <summary>
		/// [molecule]
		///
		/// Calculates vector w of the linear regression coefficients using well-known equation (in Matlab notation):
		///		w = (A'*A)\(A'*y)
		/// </summary>
		/// <param name="mA">Input matrix.</param>
		/// <param name="vy">Righthand values vector.</param>
		/// <returns>Vector of regression coefficients.</returns>
		public static float[] Solve (float[,] mA, float[] vy)
		{
			var y = Vector.Create(VectorMath.ConvertToDoubles(vy));

			var A = Matrix.Create(MatrixMath.ConvertToDoubles(mA));
			var B = Matrix.Diagonal(y);
			var x = A.Solve(B);

			//
			// get main diagonal from [x].
			var res = new float[vy.Length];
			for (int i = 0; i < vy.Length; i++)
			{
				res[i] = (float)x[i, i];
			}
			return res;
		}
	}
}
